package com.shty.wd.utils.module.Britain;


import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.shty.wd.utils.module.related.Entity;
import com.shty.wd.utils.module.related.JsonParse;
import com.shty.wd.utils.module.related.LangUtils;
import com.shty.wd.utils.module.related.Resource;
import com.shty.wd.utils.module.related.ResultData;


public class RelationAnalysis {	
	public static final String CHINA_LOCATION = "src/main/resources/Britain/location.txt"; 
	public static final String CHINA_ORG = "src/main/resources/Britain/organization.txt";
	public static final String CHINA_NAME= "src/main/resources/Britain/name.txt";
	 
	public static String DIC_LOCATION = "";
	public static String DIC_NAME = "";
	public static String DIC_ORG = "";	 

	
	public static String analyzeRelationsWithChina(String preJsonData){

		// load dictionary data
		try {
			if(DIC_LOCATION.length()==0){
				loadLocation();
			}
			/*if(DIC_NAME.length()==0){
				loadNameDic(); 
			}*/
			if(DIC_ORG.length()==0){
				loadORG();
			}
		} catch (Exception e){
			return "-2";
		}
		
		List<Entity>  flist;
		ResultData  resultJson;
		JsonParse jp = new JsonParse();
		// parsing search results
		try{
			resultJson = jp.parse(preJsonData);
			flist = resultJson.getFriendsList();	
			
		} catch(Exception e){
			return "-1";
		}	
		
		// analyze whether the friends are related to China
		try{
		    analysis(flist);
		}catch(Exception e){
			return "-3";
		}	

		// transform the analysis results into strings 
		return resultJson.creatJSON();
	}
	

	// analyze whether the friends are related to China
	public static void analysis( List<Entity> list) {
		for(int i=0; i<list.size(); i++){			
			CheckRelation(list.get(i));			
		}		
	}
	
	// analyze one friend
	public static void CheckRelation(Entity en){
		Map<String,String> result = en.getResult();
		String basis = "";
		for (Entry<String,String> entry : result.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();		
			
			if(key.contains("url")) continue;
			if(key.contains("id")) continue;
			
			// analyze the relation based on the following rules
			boolean hasname = false;
			/*String name = null;
			if(key.contains("name")) {
				name = checkNameRelation(value);	
				if(name != null)
					hasname = true;
			} else {
				name = checkChinaName(value);
				if(name != null)
					hasname = true;
			}*/
			
			boolean has1 = false;
			String location = checkLocationRelation(value);
			if(location != null)
				has1 = true;
			
			boolean has2 = false;
			String org = checkOrgRelation(value);
			if(org != null)
				has2 = true;
			
			boolean has3 = false;
			String pinyin = checkPinyin(value); 
			if(pinyin != null)
				has3 = true;

			// store the proofs for the relations
			if(hasname || has1 || has2 || has3 ){
				en.setHasRelations(true);
				basis += key+":";	

				if(hasname){
					//basis += name+", ";
				}
				if(has1){
					basis += location+", ";
				}
				if(has2){
					basis += org+", ";
				}
				if(has3){
					basis += pinyin+", ";
				}
			}			
		}
		en.setBasis(basis);
		//System.out.println(en.getBasis());
	}
	
	// Check Chinese names.
	public static String checkNameRelation(String name){
		boolean bret = false;
		bret = LangUtils.isChinese(name);		
		if(bret) return name;
		

		if(DIC_NAME.length()==0){
			return null;
		}	
		name =name.toLowerCase();	
		
		bret = checkChinaName1(name);
		if(bret)
			return name;
		else
			return null;
	}	
	
	//Check locations in the dictionary.
	public static String checkLocationRelation(String location){					
		
		if(DIC_LOCATION.length()==0){
			return null;
		}	
		String lowerlocation = location.toLowerCase();
		String reg = "([^a-zA-Z]|^)("+DIC_LOCATION+")($|[^a-zA-Z])";
		Pattern myPattern=Pattern.compile(reg);
    	Matcher myMatcher=myPattern.matcher(lowerlocation);    
    	if(myMatcher.find()){
    		if(myMatcher.group(2).trim().length()>0){
    			String matchStr = myMatcher.group(2).trim();
    			String regex = "(?i)("+matchStr+")";
    			Pattern subPattern = Pattern.compile(regex);
    			Matcher subMatcher = subPattern.matcher(location);
    			if(subMatcher.find()){
    				matchStr = subMatcher.group();
    				return matchStr;
    			}else{
    				return matchStr;
    			}
    		
    		} 		
    	}		
		return null;
	}

	// Check organizations in the dictionary.
	public static String checkOrgRelation(String organization){
		
		if(DIC_ORG.length()==0){
			return null;
		}	
		String lowerOrg = organization.toLowerCase();
		String reg = "([^a-zA-Z]|^)("+DIC_ORG+")($|[^a-zA-Z])";
		Pattern myPattern=Pattern.compile(reg);
    	Matcher myMatcher=myPattern.matcher(lowerOrg);    
    	if(myMatcher.find()){
    		if(myMatcher.group(2).trim().length()>0){
    			String matchStr = myMatcher.group(2).trim();
    			String regex = "(?i)("+matchStr+")";
    			Pattern subPattern = Pattern.compile(regex);
    			Matcher subMatcher = subPattern.matcher(organization);
    			if(subMatcher.find()){
    				matchStr = subMatcher.group();
    				return matchStr;
    			}else{
    				return matchStr;
    			}
    		
    		}
    	}		
		return null;
	}	

	// Check pinyin
	public static String checkPinyin(String Str){
		String lowerPinyin = Str.toLowerCase();		
	    String reg =  "([^a-zA-Z]|^)(((" + pinyin + ")+[\\s]+){3,}" +")($|[^a-zA-Z])";
	    Pattern myPattern=Pattern.compile(reg);
    	Matcher myMatcher=myPattern.matcher(lowerPinyin); 
    	while(myMatcher.find()){
    		if(myMatcher.group().trim().length()>0){
    			String matchStr = myMatcher.group().trim();
    			String regex = "(?i)("+matchStr+")";
    			Pattern subPattern = Pattern.compile(regex);
    			Matcher subMatcher = subPattern.matcher(Str);
    			if(subMatcher.find()){
    				matchStr = subMatcher.group();
    				return matchStr;
    			}else{
    				return matchStr;
    			}
    		}
    	}	
		return null;
	}	
	
	// Chinese family names and pinyin given names, e.g., "Kai Zheng" or "Zheng Kai".
	public static String checkChinaName(String Str){

		String lowStr =Str.toLowerCase();		

	    String reg = "(([^a-zA-Z]|^)(" + DIC_NAME +"){1}[\\s]+(" + pinyin+"){1,3}($|[^a-zA-Z]))|" + "(([^a-zA-Z]|^)(" + pinyin +"){1,3}[\\s]+(" + DIC_NAME+"){1}($|[^a-zA-Z]))";
	    Pattern myPattern=Pattern.compile(reg);
    	Matcher myMatcher=myPattern.matcher(lowStr); 

    	while(myMatcher.find()){
    		
    		// some special rules
    		
    		// rule 1: if "to" is matched, we check its case to distinguish with English word "to"
    		if(myMatcher.group(3)!=null && myMatcher.group(3).equals("to")) {
    			String temp = Str.substring(myMatcher.start(3), myMatcher.end(3));
    			if(temp.equals("To"))
    				return myMatcher.group().trim();
    		} else if(myMatcher.group(35)!=null && myMatcher.group(35).equals("to")) {
    			String temp = Str.substring(myMatcher.start(35), myMatcher.end(35));
    			if(temp.equals("To"))
    				return myMatcher.group().trim();
    		}
   
    		else if (myMatcher.group().trim().length()>0)
    			return myMatcher.group().trim();
    		
		
    	}	

		return null;
	}	
	
	// Chinese family names are in the beginning or end, e.g., "Adam Zhang" or "Zhang Adam".
	public static boolean checkChinaName1(String Str){
		boolean bret = false;

		Str =Str.toLowerCase();		
	    
	    String reg = "(^(" + DIC_NAME +"){1}[\\s]+|" + "[\\s]+(" + DIC_NAME+"){1}$)";
	    
	    Pattern myPattern=Pattern.compile(reg);
    	Matcher myMatcher=myPattern.matcher(Str); 
    	int num=0;
    	while(myMatcher.find()){
 		
    		num++;
    	}	
    	if(num>0)  bret=true;
		return bret;
	}	
	
	
	public  static void loadLocation() throws Exception{	
		if(DIC_LOCATION.length()>0) return;
		try {		
			Resource re = new Resource();
			DIC_LOCATION = re.getLocResource(CHINA_LOCATION);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}		
	}

	public  static void loadNameDic() throws Exception{	
		if(DIC_NAME.length()>0) return;
		try {		
			Resource re = new Resource();
			DIC_NAME = re.getLocResource(CHINA_NAME);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}		
	}

	public  static void loadORG() throws Exception{
		if(DIC_ORG.length()>0) return;
		try {		
			Resource re = new Resource();
			DIC_ORG = re.getLocResource(CHINA_ORG);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}		
	}
	

	private static String pinyin = "a[io]?|ou?|e[inr]?|ang?|ng|[bmp](a[io]?|[aei]ng?|ei|ie?|ia[no]|o|u)|pou|me|m[io]u|[fw](a|[ae]ng?|ei|o|u)|fou|wai|[dt](a[io]?|an|e|[aeio]ng|ie?|ia[no]|ou|u[ino]?|uan)|dei|diu|[nl](a[io]?|ei?|[eio]ng|i[eu]?|i?ang?|iao|in|ou|u[eo]?|ve?|uan|ee)|nen|lia|lun|[ghk](a[io]?|[ae]ng?|e|ong|ou|u[aino]?|uai|uang?)|[gh]ei|[jqx](i(ao?|ang?|e|ng?|ong|u)?|u[en]?|uan)|([csz]h?|r)([ae]ng?|ao|e|i|ou|u[ino]?|uan)|[csz](ai?|ong)|[csz]h(ai?|uai|uang)|zei|[sz]hua|([cz]h|r)ong|y(ao?|[ai]ng?|e|i|ong|ou|u[en]?|uan)";

}
